﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using VCards.Helpers;
using VCards.Parser;

namespace VCards;

public static class Deserializer
{
    public static VCard GetVCard(string contents)
    {
        Stopwatch sw = new();
        sw.Start();
        var vcard = new VCard()
        {
            SerializedCard = contents
        };

        if (string.IsNullOrWhiteSpace(contents) || !contents.TrimStart().StartsWith("BEGIN:VCARD") || !contents.TrimEnd().EndsWith("END:VCARD"))
        {
            throw new VCardParseException("The input is not a valid vCard file.");
        }

        var tokens = TokenParser.Parse(contents);
        foreach (var token in tokens)
        {
            if (string.IsNullOrWhiteSpace(token.Key))
            {
                continue;
            }

            var keys = AllParsers.Parsers.Keys.ToList();

            foreach (var key in keys)
            {
                var pattern = "^" + Regex.Escape(key).Replace("\\*", ".*") + "$";
                var match = Regex.IsMatch(token.Key, pattern,
                    RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);

                if (!match)
                {
                    continue;
                }

                var implementation = AllParsers.Parsers[key];
                implementation.Invoke(token, ref vcard);
            }
        }
        sw.Stop();
        Debug.WriteLine("一个内容转Vcard类时间:{0}", sw.Elapsed.TotalMilliseconds);
        return vcard;
    }

    public static IEnumerable<VCard> GetVCards(string contents)
    {
        var cards = VCardHelper.SplitCards(contents);
        cards = cards.Where(x => !string.IsNullOrWhiteSpace(x.Trim())).ToArray();
        
        return cards.Select(GetVCard).ToList();
    }

    public static IEnumerable<VCard> Deserialize(string path)
    {
        Stopwatch sw = new();
        sw.Start();
        var cards = FileHelper.ReadVCardString(path);
        sw.Stop();
        Debug.WriteLine("读取文件内容时间:{0}", sw.Elapsed.TotalMilliseconds);
        
        sw.Restart();
        cards = cards.Where(x => !string.IsNullOrWhiteSpace(x.Trim())).ToArray();
        sw.Stop();
        Debug.WriteLine("文件内容转数组时间:{0}", sw.Elapsed.TotalMilliseconds);
        sw.Restart();
        var res = cards.Select(GetVCard).ToList();
        sw.Stop();
        Debug.WriteLine("数组转类列表时间:{0}", sw.Elapsed.TotalMilliseconds);
        return res;
    }
}